Menaxhimi i te dhenave me POO
Nder operacionet kryesore qe kryejme me bazen e te dhenave jane lexim, shtim, modifikim apo fshirje te rekordeve ose sic quhen ndryshe operacionet CRUD (Create, Read, Update, Delete). Per lehtesi te menaxhimit te ketyre veprimeve do te perdorim POO. Cdo rekord te nje tabele te caktuar do ta konsiderojme nje objekt. Pra, do te ndertojme klasa te cilat perfaqesojne rekordet e tabelave te ndryshme. P.sh. per perfaqesimin e rekordeve te tabeles artikujt
do te ndertojme nje klase te quajtur Artikull
. Variablat anetare te kesaj klase do te ndertohen mbi bazen e fushave qe permban tabela perkatese. Vec tyre, kjo klase do te permbaje edhe 4 metoda kryesore si: getById(...)
, getList(...)
, save(...)
dhe delete(...)
. Duke permbledhur te gjitha veprimet qe mund te kryejme mbi nje tabele ne klasa te tilla, ne ndajme logjiken e te dhenave nga nderfaqja e perdoruesit. Keto lloj klasash ndryshe konsiderohen Model-e. Modelet nuk permbajne informacion ne lidhje me nderfaqen e perdoruesit, por me ane te tyre realizohet menaxhimi i veprimeve mbi te dhenat, sic jane operacionet CRUD.
Perpara se te ndertojme klasat specifike per cdo tabele, le te ndertojme nje klase prind BaseModel
nga e cila do te trashegohen te gjitha.
Krijojme nje skedar BaseModel.php
dhe ne te klasen BaseModel
:
<?php
require_once "Database.php";
class BaseModel {
protected $db;
function __construct() {
$this->db = new Database();
}
}
Ne nje skedar Artikull.php
ndertojme klasen Artikull
, fillimisht vetem me disa variabla anetare aq sa fusha ka tabela artikujt
:
<?php
class Artikull extends BaseModel {
private $id;
public $titulli;
public $pershkrimi;
public $data;
public $id_departament;
function __construct(array $artik = []) {
parent::__construct(); //Therrasim konstruktorin e klases prind
$this->titulli = isset($artik['titulli']) ? $artik['titulli'] : null;
$this->pershkrimi = isset($artik['pershkrimi']) ? $artik['pershkrimi'] : null;
$this->data = isset($artik['data']) ? $artik['data'] : null;
$this->id_departament = isset($artik['id_departament']) ? $artik['id_departament'] : null;
}
public function getId() {
return $this->id;
}
}
Dukeqenese fusha id
gjenerohet automatikisht ne rastin e krijimit te nje rekordi te ri ne databaze, e kemi lene me akses private
ne menyre qe mos te jete e mundur te vendoset vlere per te. E vetmja gje qe mund te kryhet mbi te eshte leximi me ane te metodes getId()
. Variablat anetare te tjere jane public
ne menyre qe te kemi mundesi aksesimi direkt.
Ne konstruktorin e klases Artikull
fillimisht therrasim konstruktorin e klases prind parent::__construct();
ne menyre qe te na inicializohet variabli i trasheguar $db
, ai i cili do te na sherbeje per te kryer operacionet CRUD ne databaze. Konstruktori i klases artikull pranon si argument nje array, i cili duhet te jete associative dhe sherben per te inicializuar variablat $titulli
, $pershkrimi
, $data
, $id_departament
.
Tashme, per te krijuar nje objekt te klases se mesiperme mund te veprojme ne dy menyra:
- Kalimi i vlerave ne konstruktor me ane te nje array associative:
<?php
$artikull = new Artikull([
"titulli" => "Titulli i artikullit",
"pershkrimi" => "Pershkrimi i artikullit...",
"data" => date("Y-m-d"),
"id_departament" => 1
]);
- Kalimi i vlerave ne anetaret perkates:
<?php
$artikull = new Artikull();
$artikull->titulli = "Titulli i artikullit";
$artikull->pershkrimi = "Pershkrimi i artikullit...";
$artikull->data = date("Y-m-d");
$artikull->id_departament = 1;
Ajo cfare duam te realizojme eshte, krijimi i metodave te meposhtme:
save()
Nese krijojme nje objekt per here te pare p.sh. si ne rastin me lart
$artikull
, fusha$artikull->id
ka vlerennull
. Nese therrasim metodensave()
mbi kete objekt do te ruhet nje rekord i ri ne tabele. Vleranull
ne fushen$id
tregon qe ky objekt nuk ka nje rekord perfaqesues ne tabele.Ne ndryshim nga rasti me lart, behet fjale per rastin kur marrim nje rekord nga baza e te dhenave dhe i krijojme nje objekt perfaqesues p.sh.
$artikull
, por ne kete rast fusha$artikull->id
nuk do te kete vlerennull
, sepse ne e morem rekordin nga databaza dhe ai e ka nje vlere ne fushenid
. Ketu kuptojme se rekordi kur therret metodensave()
do te behet thjesht update, dhe nuk krjjon rekord te ri.
getById()
- Metode statike e cila pranon si argument nje id dhe te kthen objektin perfaqesues ne databaze nqs. ekziston.delete()
- Fshin rekordin perfaqesues ne databaze te objektit qe e therret.getList()
- Metode statike e cila pranon si argument nje stringe qe permban kushtinWHERE
dhe kthen nje liste objektesh qe plotesojne kete kusht ne tabelen specifike.
save()
Implementojme fillimisht metoden save()
per te kryer edhe veprimin e shtimit, dhe te modifikimit te nje rekordi.
<?php
public function save() {
if(is_null($this->id) {
// Kryej shtimin e rekordit
} else {
// Kryej modifikimin e rekordit
}
}
Nese variabli anetar $this->id
do te jete null
, atehere duhet te kryejme nje shtim te rekordit ne tabele, perndryshe duhet thjeshte bejme update sepse rekordi eshte ekzisten ne tabele me id-ne perkatese. Pjesen e shtimit e realizojme me kodin e meposhtem:
<?php
$new_id = $this->db->insert("artikujt", [
"titulli" => $this->titulli,
"pershkrimi" => $this->pershkrimi,
"data" => $this->data,
"id_departament" => $this->id_departament
]);
return $new_id;
Me ane te variablit anetar $db
te trasheguar nga klasa prind BaseModel
, therrasim metoden insert(...)
te klases Database
. Kalojm si argumente emrin e tabeles, dhe nje array associative me fushat dhe vlerat perkatese qe do te ruhen ne tabele. Nese cdo gje shkon ne rregull do te na kthehet nje id
e rekordit te saposhtuar.
Pjesa e modifikimit realizohet nepermjet kodit te meposhtem:
<?php
$rezultati = $this->db->update("artikujt", [
"titulli" => $this->titulli,
"pershkrimi" => $this->pershkrimi,
"data" => $this->data,
"id_departament" => $this->id_departament
], "id = {$this->id}");
return $rezultati;
Ne kete rast eshte perdorur metoda update(...)
e klases Database
e cila pranon dhe si argument te trete kushtin WHERE
qe secifikon rekordin ku do te kryhet modifikimi. Bashkojme kodet e mesiperme, duke ndertuar metoden save()
te klases Artikull
:
<?php
class Artikull extends BaseModel {
private $id;
public $titulli;
public $pershkrimi;
public $data;
public $id_departament;
function __construct(array $artik = []) {
parent::__construct(); //Therrasim konstruktorin e klases prind
$this->titulli = isset($artik['titulli']) ? $artik['titulli'] : null;
$this->pershkrimi = isset($artik['pershkrimi']) ? $artik['pershkrimi'] : null;
$this->data = isset($artik['data']) ? $artik['data'] : null;
$this->id_departament = isset($artik['id_departament']) ? $artik['id_departament'] : null;
}
public function getId() {
return $this->id;
}
//Shtojme ose modifikojme nje artikull
public function save() {
if(is_null($this->id)) {
$new_id = $this->db->insert("artikujt", [
"titulli" => $this->titulli,
"pershkrimi" => $this->pershkrimi,
"data" => $this->data,
"id_departament" => $this->id_departament
]);
return $new_id;
} else {
$rezultati = $this->db->update("artikujt", [
"titulli" => $this->titulli,
"pershkrimi" => $this->pershkrimi,
"data" => $this->data,
"id_departament" => $this->id_departament
], "id = {$this->id}");
return $rezultati;
}
}
}
Per te kryer shtim te nje rekordi te ri ne tabelen artikujt
, veprojme si me poshte:
- Shtimi i nje rekordi te ri:
<?php
$artikull = new Artikull([
"titulli" => "Titulli i artikullit",
"pershkrimi" => "Pershkrimi i artikullit...",
"data" => date("Y-m-d"),
"id_departament" => 1
]);
$artikull->save();
Pas ekzekutimit te kodit te mesiperm, nese bejme nje SELECT
ne databaze do te shohim qe rekordi i ri gjendet ne tabele:
Komanda:
SELECT * FROM artikujt;
id | titulli | pershkrimi | data | id_departament |
---|---|---|---|---|
1 | Titulli i artikullit | Pershkrimi i artikullit... | 2017-02-06 | 1 |
getById(...)
Perpara se te testojme modifikimin e nje artikulli, le te implementojme metoden statike getById(...)
e cila merr nje rekord nga tabela dhe e perfaqeson me nje objekt te klases Artikull
.
<?php
public static function getById(int $id) {
$sql = "SELECT * FROM artikujt WHERE id = :id";
$db = new Database();
$rekord = $db->select($sql, [":id" => $id]);
// $rekord eshte nje array me listen e rekordeve qe u kthye
if(count($rekord)) {
// Nese ekziston rekord me kete id, krijojme nje objekt perfaqesues per te
$artikull = new Artikull();
$artikull->id = $rekord[0]["id"];
$artikull->titulli = $rekord[0]["titulli"];
$artikull->pershkrimi = $rekord[0]["pershkrimi"];
$artikull->data = $rekord[0]["data"];
$artikull->id_departament = $rekord[0]["id_departament"];
return $artikull;
} else {
return null;
}
}
Metoda getById(...)
eshte statike pasi nuk ka sens qe fillimisht te ndertojme nje objekt te klases Artikull
dhe me pas ta marrim ate nga baza e te dhenave. Per kete arsye kete metode mund ta therrasim nepermjet klases, duke i kaluar si argument thjesht nje numer, id-ne e artikullit.
Fillimisht eshte ndertuar deklarata SQL qe do te dergohet per ekzekutim. Therrasim metoden select(...)
te klases Database
per te bere marrjen e rekordit nga databaza. Ne kete rast smund te perdorim $this->db
sepse nuk mund te perdoret variabli special $this
ne nje metode statike, ndaj kemi krijuar nje objekt te ri te klases Database
. Kjo metode do te na ktheje nje array me listen e rekordeve qe kthen deklarata SQL. Kontrolli if(count($rekord))
kontrollon nqs. variabli $rekord
permban element ose jo. Nqs. permban element atehere ndertojme nje objekt $artikull
te klases Artikull
dhe i japim vlera fushave te ndryshme perkatesisht si vlerat qe mban rekordi qe morem nga baza e te dhenave. Rekordit i referohemi me $rekord[0]
sepse $rekord
eshte nje array dhe $rekord[0]
eshte elementi i pare i tij. Dukeqenese vetem nje rekord ne databaze do te jete me kete id (per arsye se id-te jane unike), edhe array $rekord
do te permbaje vetem nje element. Pasi krijohet objekti $artikull
e kthejme me ane te deklarates return
. Ne rast se nuk kthehet asnje rekord nga baza e te dhenave, p.sh. ne rastet kur id-ja nuk eshte ekzistente ne databaze, atehere kthejme null
.
Testojme metoden getById(...)
duke marre nje rekord nga tabela, dhe pasi te kemi bere nje modifikim te fushes pershkrimi
, ruajme rekordin me ane te metodes save()
:
<?php
//Marrja e artikullit:
$artikull = Artikull::getById(1);
echo $artikull->titulli; //Rezultati: Titulli i artikullit
//Modifikimi i artikullit:
$artikull->pershkrimi = "Pershkrimi i modifikuar...";
$artikull->save();
Pas ekzekutimit te kodit te mesiperm, nese bejme nje SELECT
ne databaze do te shohim qe rekordi i ri gjendet ne tabele:
Komanda:
SELECT * FROM artikujt;
id | titulli | pershkrimi | data | id_departament |
---|---|---|---|---|
1 | Titulli i artikullit | Pershkrimi i modifikuar... | 2017-02-06 | 1 |
delete(...)
Per te fshire nje artikull do te implementojme metoden delete(...)
e cila therritet nga nje objekt i tipit Artikull
dhe fshin artikullin qe e therret.
<?php
public function delete() {
$rezultati = $this->db->delete("artikujt", "id = {$this->id}");
return $rezultati;
}
Mjafton te therrasim metoden delete(...)
te klases Database
duke i kaluar si argumente, emrin e tabeles dhe kushtin WHERE
, ne kete rast id = {$this->id}
. Kjo ben qe te fshihet objekti i aktual pasi i kemi kaluar ne deklaraten e SQL-se qe te fshihet objekti qe e ka fushen id te barabarte me $this->id
, e cila eshte id-ja e objektit aktual qe ben therritjen.
getList(...)
Vec metodave te mesiperme eshte e nevojshme nje metode statike ne te cilen mund te kalojme nje kusht te caktuar, dhe na kthen listen e rekordeve te tabeles. Nje metode te tille mund ta quajme getList(...)
. Kushti qe do ti kalohet si argument eshte nje string e cila vendoset ne menyre te drejtperdrejte ne kushtin WHERE
te deklarates SQL qe dergojme per ekzekutim, ne menyre qe te na kthehet lista me rekorde.
<?php
public static function getList(string $condition = "1") {
$sql = "SELECT * FROM artikujt WHERE $condition";
$db = new Database();
$rekordet = $db->select($sql);
// $rekordet eshte nje array me listen e rekordeve qe u kthye
$artikujt = []; //Ky array do te mbaje listen e objekteve te tipit `Artikull`
if(count($rekordet)) {
foreach($rekordet as $rekord) {
//Per cdo rekord te kthyer nga databaza krijojme nje objekt:
$artikull = new Artikull();
$artikull->id = $rekord["id"];
$artikull->titulli = $rekord["titulli"];
$artikull->pershkrimi = $rekord["pershkrimi"];
$artikull->data = $rekord["data"];
$artikull->id_departament = $rekord["id_departament"];
// E shtojme objektin e krijuar ne array-n kryesor:
array_push($artikujt, $artikull);
}
//Kthejme listen e objekteve te tipit `Artikull`:
return $artikujt;
} else {
return array();
}
}
Edhe ne kete rast, ashtu si getById(...)
perdoret metoda select(...)
e klases Database
. Ne kete rast, rekordet qe kthehen mund te jene shume ndaj kalohen nepermjet nje cikli foreach
dhe per cdo rekord te kthyer nga databaza krijohet nje objekt i tipit Artikull
si perfaqesues me vlerat e tij. Me pas rekordet me radhe ruhen ne nje array $artikujt
, i cili pas iterimit ne cdo rekord, kthehet me ane te return
. Si vlere default e parametrit te metodes getList(...)
eshte vendosur vlera 1
. Kjo ben qe ne rast se perdoruesi nuk kalon asnje kusht, ne deklaraten SQL do te formohet kushti WHERE 1
, qe eshte i vertete per te gjitha rekordet sepse vlera 1
nenkupton true
. Kjo ben qe te kthehen te gjitha rekordet.
Pas ndertimit te metodave te mesiperme, kemi krijuar si perfundim nje klase Artikull
e afte per kryerjen e operacioneve CRUD mbi tabelen artikujt
, ndryshe e konsiderojme nje Model. Me poshte paraqitet implementimi i plote i saj:
<?php
// Modeli Artikull:
//Importimi i skedareve te nevojshem:
require_once 'BaseModel.php';
class Artikull extends BaseModel {
private $id;
public $titulli;
public $pershkrimi;
public $data;
public $id_departament;
function __construct(array $artik = []) {
parent::__construct();
$this->titulli = isset($artik['titulli']) ? $artik['titulli'] : null;
$this->pershkrimi = isset($artik['pershkrimi']) ? $artik['pershkrimi'] : null;
$this->data = isset($artik['data']) ? $artik['data'] : null;
$this->id_departament = isset($artik['id_departament']) ? $artik['id_departament'] : null;
}
public function getId() {
return $this->id;
}
public function save() {
if(is_null($this->id)) {
$new_id = $this->db->insert("artikujt", [
"titulli" => $this->titulli,
"pershkrimi" => $this->pershkrimi,
"data" => $this->data,
"id_departament" => $this->id_departament
]);
return $new_id;
} else {
$rezultati = $this->db->update("artikujt", [
"titulli" => $this->titulli,
"pershkrimi" => $this->pershkrimi,
"data" => $this->data,
"id_departament" => $this->id_departament
], "id = {$this->id}");
return $rezultati;
}
}
public function delete() {
$rezultati = $this->db->delete("artikujt", "id = {$this->id}");
return $rezultati;
}
public static function getById(int $id) {
$sql = "SELECT * FROM artikujt WHERE id = :id";
$db = new Database();
$rekord = $db->select($sql, [":id" => $id]);
// $rekord eshte nje array me listen e rekordeve qe u kthye
if(count($rekord)) {
// Nese ekziston rekord me kete id, krijojme nje objekt perfaqesues per te
$artikull = new Artikull();
$artikull->id = $rekord[0]["id"];
$artikull->titulli = $rekord[0]["titulli"];
$artikull->pershkrimi = $rekord[0]["pershkrimi"];
$artikull->data = $rekord[0]["data"];
$artikull->id_departament = $rekord[0]["id_departament"];
return $artikull;
} else {
return null;
}
}
public static function getList(string $condition = "1") {
$sql = "SELECT * FROM artikujt WHERE $condition";
$db = new Database();
$rekordet = $db->select($sql);
// $rekordet eshte nje array me listen e rekordeve qe u kthye
$artikujt = []; //Ky array do te mbaje listen e objekteve te tipit `Artikull`
if(count($rekordet)) {
foreach($rekordet as $rekord) {
//Per cdo rekord te kthyer nga databaza krijojme nje objekt:
$artikull = new Artikull();
$artikull->id = $rekord["id"];
$artikull->titulli = $rekord["titulli"];
$artikull->pershkrimi = $rekord["pershkrimi"];
$artikull->data = $rekord["data"];
$artikull->id_departament = $rekord["id_departament"];
// E shtojme objektin e krijuar ne array-n kryesor:
array_push($artikujt, $artikull);
}
//Kthejme listen e objekteve te tipit `Artikull`:
return $artikujt;
} else {
return array();
}
}
}